package hopital.sql;

import java.io.EOFException;
import java.sql.*;
import java.util.List;
import java.util.Properties;
import org.mariadb.jdbc.MySQLDataSource;

public final class SqlDatabase {
    private static SqlDatabase _database = null;
    private Connection _con;
    private ResultSet _rs;
    private PreparedStatement _cs;
    private final org.mariadb.jdbc.MySQLDataSource _ds;
    private SqlDatabase() throws SQLException, Exception {
           _ds=new MySQLDataSource();
           _ds.setDatabaseName("hopital");
           _ds.setPassword("");
           _ds.setPortNumber(3306);
           _ds.setServerName("127.0.0.1");
           _ds.setUserName("root");
    }

    private SqlDatabase(Properties _property) throws SQLException, Exception {
        if (_property != null) {
           _ds=new MySQLDataSource();
           _ds.setDatabaseName(_property.getProperty("DatabaseName"));
           _ds.setPassword(_property.getProperty("Password"));
           _ds.setPortNumber(Integer.valueOf(_property.getProperty("PortNumber")));
           _ds.setServerName(_property.getProperty("ServerName"));
           _ds.setUserName(_property.getProperty("UserName"));
        }else 
            throw new Exception();
    }
    
    public Connection getConnection() throws SQLException {
        return  _ds.getConnection();
    }

    public synchronized ResultSet getKey() throws Exception {
        try {
            return _cs.getGeneratedKeys();
        } catch (SQLException e) {
            throw new Exception(e.getMessage());
        }
    }

    public synchronized ResultSet doQuery(String query, Object... o) throws Exception {
        try {
            _con=_ds.getConnection();
            _cs = _con.prepareStatement(query);
            if (o != null) {
                for (int i = 0; i < o.length; i++) {
                    _cs.setObject(i + 1, o[i]);
                }
            }
            _rs = _cs.executeQuery();
            return _rs;
        } catch (SQLException e) {
            throw new Exception(e.getMessage());
        }
    }

    public synchronized boolean doNonQuery(String query, Object... o) throws Exception {
        try {
             _con=_ds.getConnection();
            _cs = _con.prepareStatement(query, PreparedStatement.RETURN_GENERATED_KEYS);
             if (o != null) {
                for (int i = 0; i < o.length; i++) {
                    _cs.setObject(i + 1, o[i]);
                }
            }
            _cs.execute();
            return true;
        } catch (SQLException e) {
            throw new Exception(e.getMessage());
        }
    }


    public synchronized static SqlDatabase getDatabase() throws SQLException, Exception {
        if (_database == null) {
            _database = new SqlDatabase();
        }
        return _database;
    }

    public synchronized static SqlDatabase getDatabase(Properties _property) throws SQLException, Exception {
           _database = new SqlDatabase(_property);
        return _database;
    }
    
    public ResultSet execute(SqlQuery _query) throws Exception{
        return doQuery(_query.getQuery(), _query.getParameters());
    }
    
    public List<Object> retrive(SqlObject _bean) throws Exception{
        return _bean.retrive(this);
    }
    
    public boolean destroy(SqlObject _bean) throws Exception{
        return _bean.destroy(this);
    }
    
    public boolean save(SqlObject _bean) throws Exception{
        return _bean.save(this);
    }
 }